/*
  Copyright (c) 2014 Dimitrij Gester

  "Smart RC TX" is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.

  "Smart RC TX" is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General
  Public License along with "Smart RC TX"; if not, write to the
  Free Software Foundation, Inc., 59 Temple Place, Suite 330,
  Boston, MA  02111-1307  USA
*/

#include <Arduino.h>
#include "SoftUartTx.h"

#define OUTPUT_PIN 12

static volatile uint16_t outframe;

static void setupTimer2()
{
	TCCR2A = (0x2 << WGM20); // waveform generation mode: CTC
	TIMSK2 |= (1 << OCIE2A); // enable interrupt

	OCR2A = 255;
	TCCR2B = 0; // clock source divider: 0-> off; 1-> 1; 5->128; 6->256; 7->1024
}

static void startTimer2()
{
	OCR2A = 62; //F_CPU / 125000; //62
	TCCR2B = (0x1 << CS20); // clock source divider: 1-> 1; 5->128; 6->256; 7->1024
}

static void stopTimer2()
{
	TCCR2B &= ~(_BV(3) - 1);
}

void softUartInit()
{
	pinMode(OUTPUT_PIN, OUTPUT);
	digitalWrite(OUTPUT_PIN, HIGH);
	setupTimer2();
}

void softUartTransmitByte(const uint8_t b)
{
	while(outframe)
		asm("nop"::);

    outframe = (3 << 9) | (((uint8_t) b) << 1);
	
	startTimer2();
}

void softUartTransmit(const uint8_t *buffer, size_t size)
{
  while (size--) {
    softUartTransmitByte(*buffer++);
  }
}


ISR(TIMER2_COMPA_vect) {
	uint16_t data = outframe;
	
	digitalWrite(OUTPUT_PIN, (data & 1));
	
	if (1 == data)
	stopTimer2();
	
	outframe = data >> 1;
}
